﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using Peak.ApplicationServices.CsvReader;
using Peak.Core;
using Microsoft.ReportingServices.DataProcessing;
using SharpArch.Core.CommonValidator;

namespace Peak.ApplicationServices
{
  public class StoriesCSVReader
  {
    private readonly string _importerName;
    private readonly char _separator;
    private List<string> _errors;

    public StoriesCSVReader(string importerName)
      : this(importerName, ';')
    {      
    }

    public StoriesCSVReader(string importerName, char sepearator)
    {
      _importerName = importerName;
      _separator = sepearator;
      _errors = new List<string>();
    }

    public IList<string> Errors
    {
      get
      {
        return _errors;
      }
    }
    public IList<Story> Import(TextReader input)
    {
      using (CsvReader.CsvReader reader = new CsvReader.CsvReader(input, true, _separator))
      {
        reader.SkipEmptyLines = true;
        reader.SupportsMultiline = true;
        reader.MissingFieldAction = MissingFieldAction.ReplaceByNull;
        List<Story> result = new List<Story>();
        while (reader.ReadNextRecord())
        {
          if(IsEmpty(reader))
            continue;
          
          Story story = new Story();
          FillStory(story, reader);
          if (!story.IsValid())
          {
            foreach (IValidationResult validationResult in story.ValidationResults())
            {
              _errors.Add(validationResult.PropertyName + ";" + validationResult.Message);
            }
          }
          else
            result.Add(story);
        }
        return result;
      }
    }

    private bool IsEmpty(CsvReader.CsvReader reader)
    {
      string[] headers = reader.GetFieldHeaders();
      foreach(string header in headers)
      {
        if(!string.IsNullOrEmpty(header) && reader.GetFieldIndex(header) != -1 && !string.IsNullOrEmpty(reader[header]))
          return false;
      }
      return true;
    }

    private void FillStory(Story story, CsvReader.CsvReader reader)
    {
      if(reader.GetFieldIndex("Category") != -1 && !string.IsNullOrEmpty(reader["Category"]))
        story.Category = reader["Category"];
      if (reader.GetFieldIndex("Name") != -1 && !string.IsNullOrEmpty(reader["Name"]))
        story.Name = reader["Name"];
      if (reader.GetFieldIndex("Description") != -1 && !string.IsNullOrEmpty(reader["Description"]))
        story.Description = reader["Description"];
      if (reader.GetFieldIndex("Priority") != -1 && !string.IsNullOrEmpty(reader["Priority"]))
        story.Priority = Convert.ToInt32(reader["Priority"]);
      if (reader.GetFieldIndex("Status") != -1 && !string.IsNullOrEmpty(reader["Status"]))
        story.Status = (StoryStatus)Enum.Parse(typeof(StoryStatus), reader["Status"]);      
      if (reader.GetFieldIndex("HowToDemo") != -1 && !string.IsNullOrEmpty(reader["HowToDemo"]))
        story.HowToDemo = reader["HowToDemo"];
      if (reader.GetFieldIndex("StoryPoints") != -1 && !string.IsNullOrEmpty(reader["StoryPoints"]))
        story.StoryPoints = Convert.ToInt32(reader["StoryPoints"]);  
      if(reader.GetFieldIndex("Created") != -1 && !string.IsNullOrEmpty(reader["Created"]))
      {
        story.Created = Convert.ToDateTime(reader["Created"]); 
      }
      else
      {
        story.Created = DateTime.Now;
      }
      if (reader.GetFieldIndex("CreatedBy") != -1 && !string.IsNullOrEmpty(reader["CreatedBy"]))
      {
        story.Created = Convert.ToDateTime(reader["CreatedBy"]);
      }
      else
      {
        story.CreatedBy = _importerName;
      }
    }    
  }
}